using System;
using System.Drawing;

namespace Third
{
    public class Project
    {
        class Rectangle
        {
            public readonly float Width, Height;

            public Rectangle(float width, float height)
            {
                Width = width;
                Height = height;
            }

            public void Deconstruct(out float width, out float height)
            {
                width = Width;
                height = Height;
            }
        }

        public static void Test1()
        {
            var rect = new Rectangle(3, 4);
            // 调用解构器
            (float width, float height) = rect;
            Console.WriteLine(width + " " + height); // 3 4
        }

        public int Property { get; set; }

        public const string Message = "Hi Vicrtoria";

        class ClassFinalizerTest
        {
            // 终结器, 是 C# 语言重写 Object 的 Finalize 方法的语句。
            ~ClassFinalizerTest()
            {
                
            }
        }

        public static void Test2()
        {
            int count = 321;
            var name = nameof(count);
            Console.WriteLine(name); // count
            var str = "ffffff";
            Console.WriteLine(nameof(str)); // str
            Console.WriteLine(nameof(str.Length)); // Length
        }

        class A
        {
            public string name = "231";
        }
        class A1 : A    // A1 继承 A
        {
            public long a1 = 1000;
        }

        class A2 : A1    // A2 继承 A1
        {
            public long a2 = 2000;
        }
        public static void Test3()
        {
            var a = new A2();
            Console.WriteLine(a.a1);  // 1000
            Console.WriteLine(a.a2);  // 2000
            Console.WriteLine(a.name);  // "231"

            // 多态, 父类变量可以指向子类的对象
            A aa = new A1();
            A1 aa1 = (A1)aa;
            Console.WriteLine(aa == aa1); // True

            // as 运算符在转换时如果出错会返回 null
            var a2 = aa as A2;
            if (a2 != null)
            {
                Console.WriteLine(a2.a2);
            }
            var at1 = aa as A1;
            if (at1 != null)
            {
                Console.WriteLine(at1.a1); // 1000
            }

            // is 运算符判断是否是某个类型，如果是则转换为这个类型
            if (at1 is A1 newA1)
            {
                Console.WriteLine(newA1.name); // 231
            }
        }

        public class Father
        {
            public string Name;
            public virtual decimal Number
            {
                get => 0;
            }

            public virtual bool check()
            {
                return Number == 0;
            }
        }
        
        public class Son: Father
        {
            // 通过 override 重写虚方法
            public override decimal Number { get => 18; }

            public override bool check()
            {
                return Number == 18;
            }
        }

        // abstract 声明抽象类，抽象类不能被实例化
        public abstract class AbstractClass
        {
            // 抽象方法
            public abstract int Number { get; }

            public void check()
            {
                
            }
        }

        public class ASon : AbstractClass
        {
            public override int Number { get; }
        }
        
        public class MyClassFather
        {
            public int Number = 1;

            public virtual void check()
            {
                Console.WriteLine($"Number = {Number}");
            }
        }
        
        public class MyClassSong: MyClassFather
        {
            public new int  Number = 3;
            
            public new void check()
            {
                Console.WriteLine($"Number = {Number}");
            }
        }
        
        public class MyClassSong2: MyClassFather
        {
            public new int  Number = 7;
            
            public override void check()
            {
                Console.WriteLine($"Number = {Number}");
            }
        }
        

        public static void Test4()
        {

            // new 修饰符的作用只是隐藏了父类成员，在转换为父类的时候，会调用父类的成员
            MyClassSong myClassSong = new MyClassSong();
            myClassSong.check(); // Number = 3
            MyClassFather myClassFather = myClassSong;
            myClassFather.check(); // Number = 1
            
            // override 重写父类成员，在转寒为父类使用的时候，会调用子类重写的成员
            MyClassSong2 myClassSong2 = new MyClassSong2();
            myClassSong2.check(); // Number = 7
            MyClassFather myClassFather2 = myClassSong2;
            myClassFather2.check(); // Number = 7
        }

      
        
        public struct MyStruct
        {
            public int x;
            public int y;

            public MyStruct(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }
        
        public static void Test5()
        {
            MyStruct myStruct =new MyStruct(1, 2);
            Console.WriteLine(myStruct.x + " " + myStruct.y); // 1 2
            MyStruct myStruct2 = new MyStruct();
            Console.WriteLine(myStruct2.x + " " + myStruct2.y); // 0 0 

        }

        public interface IInterface
        {
            bool MoveNext();
            object Current { get; }
            void Reset();

            void Name();
        }
        
        public interface IInterface2 : IInterface
        {
            // 从  IInterface 派生
        }
        
        public interface IName
        {
            string Name();
        }
        
        public class MyImp:IInterface, IName
        {
            private int count = 11;
            public bool MoveNext()
            {
                return count-- > 0;
            }

            public object Current { get => count; }
            public void Reset()
            {
                throw new NotImplementedException();
            }

            void IInterface.Name()
            {
                Console.WriteLine("IInterface.Name()");
            }

            string IName.Name()
            {
                Console.WriteLine("IName.Name()");
                return "IName";
            }
        }
        public static void Test6()
        {
            IInterface myImp = new MyImp();
            while (myImp.MoveNext())
            {
                Console.Write($"{myImp.Current} "); // 10 9 8 7 6 5 4 3 2 1 0 
            }

        }
        
        public enum  MyEnum
        {
            One, Two, Three
        }
        
        public enum MyByteEnum:long
        {
            // 可以指定数字类型，也可以显式的指定数字
            One = 1, Tow, Three = 90, Four
        }
        public static void Test7()
        {
            MyEnum one = MyEnum.One;
            MyEnum Two = MyEnum.Two;
            MyEnum Three = MyEnum.Three;
            
            Console.WriteLine((long)MyByteEnum.Four); // 91
            Console.WriteLine(MyByteEnum.Four.ToString()); // Four
            Console.WriteLine(sizeof(MyByteEnum)); // 8
        }
        
        public class Stack<T>
        
        {
            private int position;
            private T[] data = new T[100];
            public void Push(T obj) => data[position++] = obj;
            public T Pop() => data[--position];

            void Zap<T>(T[] array)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    // default 关键字可以用于获取泛型类型参数的默认值，引用类型默认值是 null，值默认值是0
                    array[i] = default(T);
                }
            }
        }
        
        public class MStack<T, T1, T2>
        {
            void Init<T>(T[] array) where T:new() // where 约束泛型
            {
                
            }
            
        }
        
        public static void Test8()
        {
            
            var stack = new Stack<int>();
            stack.Push(1);
            var stack2 = new Stack<String>();
            stack2.Push("1");
            var stack3 = new Stack<double>();
            stack3.Push(1.0);

            Type a = typeof(Stack<>);
        }
        
        public interface IComparerOut<out T>
        {
        }
        public interface IComparerIn<in T>
        {
            
        }
    }
    
  
}

